package com.iplant.base.utils.annotation.join;

import com.alibaba.fastjson.JSON;
import com.iplant.base.po.enums.DBSchemas;
import com.iplant.base.utils.annotation.DBBaseValue;
import com.iplant.base.utils.general.StringUtils;

import java.lang.reflect.Field;
import java.util.ArrayList;
import java.util.List;
import java.util.Map;

/**
 * @author xiuto
 */
public class DBJoinValue  extends DBBaseValue {


    /**
     * 表名   可能为空 未赋值
     */
    public String tableName = "";


    /**
     * 数据库
     */
    public DBSchemas Schemas = DBSchemas.Basic;

    /**
     * 关联类型
     */
    public DBJoin.DBJoinMode JoinMode = DBJoin.DBJoinMode.Left;

    public String getJoinMode(){

        switch ( JoinMode   ){

            case Left:
                return " Left ";
            case Inner:
                return " Inner ";
            case Right:
                return " Right ";
        }
        return " Left ";
    }


    /**
     * 关联顺序
     */
    public int JoinIndex = 1;

    /**
     * 关联条件
     */
    public List<String> ConditionalJoin = new ArrayList<>();


    /**
     * 字段的数据库类型
     */

    public String TypeName = "String";


    public Field POField;

    public DBJoinValue Clone() {
        DBJoinValue wDBJoinValue = new DBJoinValue();
        wDBJoinValue.name = this.name;
        wDBJoinValue.viewName = this.viewName;
        wDBJoinValue.tableName = this.tableName;
        wDBJoinValue.tableAsName = this.tableAsName;
        wDBJoinValue.Schemas = this.Schemas;
        wDBJoinValue.JoinMode = this.JoinMode;
        wDBJoinValue.JoinIndex = this.JoinIndex;
        wDBJoinValue.ConditionalJoin = this.ConditionalJoin;
        wDBJoinValue.TypeName = this.TypeName;
        wDBJoinValue.POField = this.POField;

        return wDBJoinValue;
    }

    private DBJoinValue() {
    }

    public DBJoinValue(DBJoin wDBJoin, Field wField,String wMainTableAsName) {
        this.name = wDBJoin.name();
        this.viewName = wField.getName();
        this.tableName = wDBJoin.tableName();
        this.tableAsName = wDBJoin.tableAsName();
        this.Schemas = wDBJoin.Schemas();
        this.JoinMode = wDBJoin.JoinMode();
        this.JoinIndex = wDBJoin.JoinIndex();
        if (wDBJoin.ConditionalJoin() != null && wDBJoin.ConditionalJoin().length > 0) {
            this.ConditionalJoin = StringUtils.parseList(wDBJoin.ConditionalJoin());
        }
        if(StringUtils.isNotEmpty(wDBJoin.MainTableField())){
            this.ConditionalJoin.add( StringUtils.Format("{0}.{1} = {2}.ID",wMainTableAsName,wDBJoin.MainTableField(), wDBJoin.tableAsName()));
        }

        this.POField=wField;
        this.TypeName = wField.getType().getSimpleName();

    }

    public void setValue(Map<String,Object> wReader){
        if(!wReader.containsKey(viewName))
            return;

        if(wReader.get(viewName)==null)
            return;

        switch (TypeName.toLowerCase()) {

            case "int":
            case "integer":
            case "long":
            case "char":
            case "character":
            case "double":
            case "float":
            case "short":
            case "byte":
            case "string":
            case "calendar":
            case "date":
                break;
            case "boolean":
                wReader.put(viewName, StringUtils.parseBoolean(wReader.get(viewName)) );
                break;
            default:
                if(TypeName.toLowerCase().contains("list")||TypeName.toLowerCase().contains("array")){
                    if(POField==null) {
                        wReader.put(viewName, StringUtils.splitList(wReader.get(viewName).toString(), ","));
                    }
                    else{
                        if(POField.getGenericType().getTypeName().contains("Integer")
                                ||POField.getGenericType().getTypeName().contains("Long")
                                ||POField.getGenericType().getTypeName().contains("Short")
                                ||POField.getGenericType().getTypeName().contains("byte")){
                            wReader.put(viewName, StringUtils.parseIntList(wReader.get(viewName), ","));
                        }else if(POField.getGenericType().getTypeName().contains("Double")
                                ||POField.getGenericType().getTypeName().contains("Float") ){
                            wReader.put(viewName, StringUtils.parseDoubleList(wReader.get(viewName), ","));
                        } else{
                            wReader.put(viewName, StringUtils.splitStringList(wReader.get(viewName), ","));
                        }
                    }
                }else if(TypeName.toLowerCase().contains("map")){
                    wReader.put(viewName, JSON.parseObject(wReader.get(viewName).toString(),Map.class));
                }
                break;
        }
    }

}
